Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(rate-limiting): counters accuracy with redis policy & sync_rate #11859

Merged
merged 2 commits into from
Nov 7, 2023

Conversation

samugi
Copy link
Member

@samugi samugi commented Oct 26, 2023

Summary

When the periodic sync to redis feature is turned on, using the sync_rate configuration option, keys are incremented by 2 instead of 1 for requests that arrive after the sync_rate interval has expired.

This happens because after each sync, the key is loaded from redis using incr (see: #10559) however the next call to increment also adds 1 to the counter, so the key is incremented twice every time it's loaded from redis. In other words there can be 2 increments for the same request: here and then here.

This fix sets a negative delta for the key when
conf.sync_rate ~= SYNC_RATE_REALTIME and the key was loaded from redis to account for the prior increment.

Checklist

  • The Pull Request has tests
  • A changelog file has been created under changelog/unreleased/kong or skip-changelog label added on PR if changelog is unnecessary. README.md
  • (no) There is a user-facing docs PR against https://github.com/Kong/docs.konghq.com - PUT DOCS PR HERE

Full changelog

  • [Implement ...]

Issue reference

KAG-2906

@samugi samugi marked this pull request as draft October 26, 2023 17:33
@samugi samugi force-pushed the fix/rate-limiting-redis-sync branch 2 times, most recently from b61685d to 36b8701 Compare October 27, 2023 10:44
@pull-request-size pull-request-size bot added size/L and removed size/M labels Oct 27, 2023
When the periodic sync to redis feature is turned on, using the
`sync_rate` configuration option, keys are incremented by steps of 2
instead of 1 for requests that arrive after the `sync_rate` interval
has expired.

This happens because after each sync, the key is loaded again from redis
and also incremented atomically (see: #10559)
however the next call to `increment` also adds 1 to its value, so
the key is incremented by 2 every time it's loaded from redis.

This fix sets a negative delta for the key when
`conf.sync_rate ~= SYNC_RATE_REALTIME` and the key was loaded from redis
in order to invalidate the next call to `increment`.
@samugi samugi force-pushed the fix/rate-limiting-redis-sync branch from 36b8701 to 9804330 Compare October 27, 2023 12:58
@samugi samugi changed the title fix(rate-limiting): redis async updates fix(rate-limiting): counters accuracy with redis policy & sync_rate Oct 27, 2023
@samugi samugi marked this pull request as ready for review October 27, 2023 13:02
@samugi
Copy link
Member Author

samugi commented Oct 31, 2023

the PR is ready. Holding on merge for a while, since the same logic is being investigated in https://github.com/Kong/kong-ee/pull/6253 just in case it requires any adjustments. @ADD-SP @StarlightIbuki let me know when you think this can be moved forward. (adding do not merge label because of this).

Update: no conflicts came up, I think this is ready to merge.

@samugi samugi merged commit 3a0a1f9 into master Nov 7, 2023
37 of 38 checks passed
@samugi samugi deleted the fix/rate-limiting-redis-sync branch November 7, 2023 08:39
windmgc pushed a commit that referenced this pull request Jan 24, 2024
…11859)

* fix(rate-limiting): redis async updates

When the periodic sync to redis feature is turned on, using the
`sync_rate` configuration option, keys are incremented by steps of 2
instead of 1 for requests that arrive after the `sync_rate` interval
has expired.

This happens because after each sync, the key is loaded again from redis
and also incremented atomically (see: #10559)
however the next call to `increment` also adds 1 to its value, so
the key is incremented by 2 every time it's loaded from redis.

This fix sets a negative delta for the key when
`conf.sync_rate ~= SYNC_RATE_REALTIME` and the key was loaded from redis
in order to invalidate the next call to `increment`.

Includes a small code refactor
windmgc pushed a commit that referenced this pull request Mar 7, 2024
…11859)

* fix(rate-limiting): redis async updates

When the periodic sync to redis feature is turned on, using the
`sync_rate` configuration option, keys are incremented by steps of 2
instead of 1 for requests that arrive after the `sync_rate` interval
has expired.

This happens because after each sync, the key is loaded again from redis
and also incremented atomically (see: #10559)
however the next call to `increment` also adds 1 to its value, so
the key is incremented by 2 every time it's loaded from redis.

This fix sets a negative delta for the key when
`conf.sync_rate ~= SYNC_RATE_REALTIME` and the key was loaded from redis
in order to invalidate the next call to `increment`.

Includes a small code refactor
windmgc pushed a commit that referenced this pull request Mar 8, 2024
…11859)

* fix(rate-limiting): redis async updates

When the periodic sync to redis feature is turned on, using the
`sync_rate` configuration option, keys are incremented by steps of 2
instead of 1 for requests that arrive after the `sync_rate` interval
has expired.

This happens because after each sync, the key is loaded again from redis
and also incremented atomically (see: #10559)
however the next call to `increment` also adds 1 to its value, so
the key is incremented by 2 every time it's loaded from redis.

This fix sets a negative delta for the key when
`conf.sync_rate ~= SYNC_RATE_REALTIME` and the key was loaded from redis
in order to invalidate the next call to `increment`.

Includes a small code refactor
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants